package coretest;

public class ControlUnitTest {
	core.RegisterClass rb;
	core.ControlUnitClass cu;
	public ControlUnitTest(){
		core.PsrClass psr = new core.PsrClass();
		core.AluClass alu = new core.AluClass(psr);
		rb = new core.RegisterClass();
		core.MemoryClass mem = new core.MemoryClass();
		cu = new core.ControlUnitClass(alu, rb, mem, psr);

		//Arithmetic Operations and Tests:
		mem.setWord(0, new core.InstructionClass("NOP").getByteCode());
		cu.setPC((short)0);
		cu.processNextInstruction();

		mem.setWord(1, new core.InstructionClass("INC R0").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(0) == 1);

		mem.setWord(2, new core.InstructionClass("INC R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == 1);

		mem.setWord(3, new core.InstructionClass("INC R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == 2);

		mem.setWord(4, new core.InstructionClass("DEC R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == 1);

		mem.setWord(5, new core.InstructionClass("ADD R1, R0").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == 2);

		mem.setWord(6, new core.InstructionClass("ADD R1, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == 4);

		mem.setWord(7, new core.InstructionClass("SUB R1, R0").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == 3);

		mem.setWord(8, new core.InstructionClass("ADD R2, 0x0010").getByteCode());
		mem.setWord(9, new core.InstructionClass("ADD R2, 0x0010").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 16);

		mem.setWord(10, new core.InstructionClass("ADD R2, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 19);

		mem.setWord(0xB, new core.InstructionClass("SUB R2, R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 0);
		assert(psr.getFlags() == 3);

		mem.setWord(0xC, new core.InstructionClass("DEC R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == -1);
		assert(psr.getFlags() == 4);

		mem.setWord(0xD, new core.InstructionClass("ADD R2, 0x7FFF").getByteCode());
		mem.setWord(0xE, new core.InstructionClass("ADD R2, 0x7FFF").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 32766);
		assert(psr.getFlags() == 1);

		mem.setWord(0xF, new core.InstructionClass("INC R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 32767);
		assert(psr.getFlags() == 0);

		mem.setWord(0x10, new core.InstructionClass("INC R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == -32768);
		assert(psr.getFlags() == 12);

		mem.setWord(0x11, new core.InstructionClass("ADC R3, 0x0001").getByteCode());
		mem.setWord(0x12, new core.InstructionClass("ADC R3, 0x0001").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == 1);
		assert(psr.getFlags() == 0);

		mem.setWord(0x13, new core.InstructionClass("SUB R2, 0x0001").getByteCode());
		mem.setWord(0x14, new core.InstructionClass("SUB R2, 0x0001").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 32767);
		assert(psr.getFlags() == 9);

		mem.setWord(0x15, new core.InstructionClass("SBC R3, R0").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == -1);
		assert(psr.getFlags() == 4);
		System.out.println("Control Unit - Arithmetic OK");
		
		//Tests for logic instructions

		//Cleanup:
		mem.setWord(0x16, new core.InstructionClass("SUB R2, R2").getByteCode());
		mem.setWord(0x17, new core.InstructionClass("SUB R1, R1").getByteCode());
		mem.setWord(0x18, new core.InstructionClass("SUB R0, R0").getByteCode());
		mem.setWord(0x19, new core.InstructionClass("SUB R3, R3").getByteCode());
		this.runNVerbose(4, false);
		this.testZero();

		mem.setWord(0x1A, new core.InstructionClass("ADD R2, 0x0004").getByteCode());
		mem.setWord(0x1B, new core.InstructionClass("ADD R2, 0x0004").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 0x0004);

		mem.setWord(0x1C, new core.InstructionClass("CMP R3, R2").getByteCode());
		cu.processNextInstruction();
		assert(psr.getFlags() == (short)4);

		mem.setWord(0x1D, new core.InstructionClass("CMP R2, R3").getByteCode());
		cu.processNextInstruction();
		assert(psr.getFlags() == (short)0);

		mem.setWord(0x1E, new core.InstructionClass("CMP R2, R2").getByteCode());
		cu.processNextInstruction();
		assert(psr.getFlags() == 3);

		mem.setWord(0x1F, new core.InstructionClass("AND R2, R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 0x0004);
		assert(psr.getFlags() == (short)0);

		mem.setWord(0x20, new core.InstructionClass("AND R2, R3").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == 0x0000);
		assert(psr.getFlags() == (short)2);

		mem.setWord(0x21, new core.InstructionClass("OR R2, 0xF76B").getByteCode());
		mem.setWord(0x22, new core.InstructionClass("OR R2, 0xF76B").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == (short)0xF76B);
		assert(psr.getFlags() == (short)4);

		mem.setWord(0x23, new core.InstructionClass("OR R1, 0x0893").getByteCode());
		mem.setWord(0x24, new core.InstructionClass("OR R1, 0x0893").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x0893);
		assert(psr.getFlags() == (short)0);

		mem.setWord(0x25, new core.InstructionClass("AND R1, R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x0003);
		assert(psr.getFlags() == (short)0);

		mem.setWord(0x26, new core.InstructionClass("XOR R1, R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0xF768);
		assert(psr.getFlags() == (short)4);

		mem.setWord(0x27, new core.InstructionClass("XOR R1, 0xBA69").getByteCode());
		mem.setWord(0x28, new core.InstructionClass("XOR R1, 0xBA69").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x4D01);
		assert(psr.getFlags() == (short)0);

		mem.setWord(0x29, new core.InstructionClass("SHL R3, 0x4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == (short)0x0000);
		assert(psr.getFlags() == (short)2);

		mem.setWord(0x2A, new core.InstructionClass("INC R3").getByteCode());
		cu.processNextInstruction();
		mem.setWord(0x2B, new core.InstructionClass("SHL R3, 0x4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == (short)0x0010);
		assert(psr.getFlags() == (short)0);

		mem.setWord(0x2C, new core.InstructionClass("SHL R1, 0x4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0xD010);

		mem.setWord(0x2D, new core.InstructionClass("SHR R1, 0x4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0xFD01);

		mem.setWord(0x2E, new core.InstructionClass("SHR R1, 0x4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0xFFD0);

		mem.setWord(0x2F, new core.InstructionClass("AND R1, 0x7FFF").getByteCode());
		mem.setWord(0x30, new core.InstructionClass("AND R1, 0x7FFF").getByteCode2());
		cu.processNextInstruction();
		mem.setWord(0x31, new core.InstructionClass("SHR R1, 0x4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x07FD);

		System.out.println("Control Unit - Logic OK");

		//Tests for Data movement instructions

		mem.setWord(0x32, new core.InstructionClass("MOV R2, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == (short)0x07FD);

		mem.setWord(0x33, new core.InstructionClass("MOV R1, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x07FD);

		mem.setWord(0x34, new core.InstructionClass("MOV 0x0700 ,R1").getByteCode());
		mem.setWord(0x35, new core.InstructionClass("MOV 0x0700 ,R1").getByteCode2());
		cu.processNextInstruction();
		assert(mem.getWord(0x0700) == (short)0x07FD);

		mem.setWord(0x36, new core.InstructionClass("MOV R3 ,0x0700").getByteCode());
		mem.setWord(0x37, new core.InstructionClass("MOV R3,0x0700").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == (short)0x07FD);

		mem.setWord(0x38, new core.InstructionClass("AND R3,0x700").getByteCode());
		mem.setWord(0x39, new core.InstructionClass("AND R3,0x700").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == (short)0x0700);

		mem.setWord(0x3A, new core.InstructionClass("MOV R5,[R3]").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(5) == (short)0x07FD);

		mem.setWord(0x3B, new core.InstructionClass("INC R3").getByteCode());
		cu.processNextInstruction();
		mem.setWord(0x3C, new core.InstructionClass("MOV [R3],R5").getByteCode());
		cu.processNextInstruction();
		assert(mem.getWord(0x0701) == (short)0x07FD);

		mem.setWord(0x3D, new core.InstructionClass("LDR R1,0x723").getByteCode());
		mem.setWord(0x3E, new core.InstructionClass("LDR R1,0x723").getByteCode2());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x0723);

		mem.setWord(0x3F, new core.InstructionClass("SPB R2, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == (short)0x0007);
		assert(rb.getRegister(1) == (short)0x0023);

		mem.setWord(0x40, new core.InstructionClass("LDR R1, 0x723").getByteCode());
		mem.setWord(0x41, new core.InstructionClass("LDR R1, 0x723").getByteCode2());
		cu.processNextInstruction();
		mem.setWord(0x42, new core.InstructionClass("MLB R2, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x0723);
		assert(rb.getRegister(2) == (short)0x0023);

		mem.setWord(0x43, new core.InstructionClass("MHB R2, R1").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(1) == (short)0x0723);
		assert(rb.getRegister(2) == (short)0x2323);
		
		mem.setWord(0x44, new core.InstructionClass("MVN R10, R2").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(2) == (short)0x2323);
		assert(rb.getRegister(10) == (short)0xDCDC);
		assert(psr.getN() == 1);
		assert(psr.getZ() == 0);

		System.out.println("Control Unit - Data Movement OK");

		//Stack tests
		rb.setSP((short)0x700);
		mem.setWord(0x45, new core.InstructionClass("PUSH R1").getByteCode());
		cu.processNextInstruction();
		assert(mem.getWord((short)0x700) == 0x0723);
		assert(rb.getSP() == 0x06FF);

		mem.setWord(0x46, new core.InstructionClass("PUSH R2").getByteCode());
		cu.processNextInstruction();
		assert(mem.getWord((short)0x6FF) == 0x2323);
		assert(rb.getSP() == 0x06FE);

		mem.setWord(0x47, new core.InstructionClass("POP R3").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(3) == 0x2323);
		assert(rb.getSP() == 0x06FF);

		mem.setWord(0x48, new core.InstructionClass("POP R4").getByteCode());
		cu.processNextInstruction();
		assert(rb.getRegister(4) == 0x0723);
		assert(rb.getSP() == 0x0700);

		System.out.println("Control Unit - Stack OK");

		//Tests for control flow instructions

		//Load Registers 0x200
		mem.setWord(0x200, new core.InstructionClass("LDR R0, 0x0000").getByteCode());
		mem.setWord(0x201, new core.InstructionClass("LDR R0, 0x0000").getByteCode2());
		mem.setWord(0x202, new core.InstructionClass("LDR R1, 0x0001").getByteCode());
		mem.setWord(0x203, new core.InstructionClass("LDR R1, 0x0001").getByteCode2());
		mem.setWord(0x204, new core.InstructionClass("LDR R2, 0x0020").getByteCode());
		mem.setWord(0x205, new core.InstructionClass("LDR R2, 0x0020").getByteCode2());
		mem.setWord(0x206, new core.InstructionClass("LDR R3, 0x0300").getByteCode());
		mem.setWord(0x207, new core.InstructionClass("LDR R3, 0x0300").getByteCode2());
		mem.setWord(0x208, new core.InstructionClass("LDR R4, 0x4000").getByteCode());
		mem.setWord(0x209, new core.InstructionClass("LDR R4, 0x4000").getByteCode2());
		mem.setWord(0x20A, new core.InstructionClass("RET").getByteCode());

		//Clean registers 0x300
		mem.setWord(0x300, new core.InstructionClass("LDR R0, 0x0000").getByteCode());
		mem.setWord(0x301, new core.InstructionClass("LDR R0, 0x0000").getByteCode2());
		mem.setWord(0x302, new core.InstructionClass("LDR R1, 0x0000").getByteCode());
		mem.setWord(0x303, new core.InstructionClass("LDR R1, 0x0000").getByteCode2());
		mem.setWord(0x304, new core.InstructionClass("LDR R2, 0x0000").getByteCode());
		mem.setWord(0x305, new core.InstructionClass("LDR R2, 0x0000").getByteCode2());
		mem.setWord(0x306, new core.InstructionClass("LDR R3, 0x0000").getByteCode());
		mem.setWord(0x307, new core.InstructionClass("LDR R3, 0x0000").getByteCode2());
		mem.setWord(0x308, new core.InstructionClass("LDR R4, 0x0000").getByteCode());
		mem.setWord(0x309, new core.InstructionClass("LDR R4, 0x0000").getByteCode2());
		mem.setWord(0x30A, new core.InstructionClass("RET").getByteCode());

		mem.setWord(0x49, new core.InstructionClass("CAL 0x200").getByteCode());
		mem.setWord(0x4A, new core.InstructionClass("CAL 0x200").getByteCode2());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		this.runNVerbose(6, false);
		this.testValues();
		assert(cu.getPC() == 0x04B);

		mem.setWord(0x4B, new core.InstructionClass("CAL 0x300").getByteCode());
		mem.setWord(0x4C, new core.InstructionClass("CAL 0x300").getByteCode2());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x300);
		this.runNVerbose(6, false);
		this.testZero();
		assert(cu.getPC() == 0x04D);

		mem.setWord(0x4D, new core.InstructionClass("JAL 0x200").getByteCode());
		mem.setWord(0x4E, new core.InstructionClass("JAL 0x200").getByteCode2());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		this.runNVerbose(5, false);
		this.testValues();
		assert(cu.getPC() == 0x20A);
		cu.setPC((short)0x4F);
		
		mem.setWord(0x4F, new core.InstructionClass("LDR R5, 0x300").getByteCode());
		mem.setWord(0x50, new core.InstructionClass("LDR R5, 0x300").getByteCode2());
		mem.setWord(0x51, new core.InstructionClass("CAL [R5]").getByteCode());
		cu.processNextInstruction();
		cu.processNextInstruction();
		assert(cu.getPC() == 0x300);
		this.runNVerbose(6, false);
		this.testZero();
		assert(cu.getPC() == 0x52);

		mem.setWord(0x52, new core.InstructionClass("LDR R5, 0x200").getByteCode());
		mem.setWord(0x53, new core.InstructionClass("LDR R5, 0x200").getByteCode2());
		mem.setWord(0x54, new core.InstructionClass("JAL [R5]").getByteCode());
		cu.processNextInstruction();
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		this.runNVerbose(5, false);
		this.testValues();
		assert(cu.getPC() == 0x20A);
		cu.setPC((short)0x55);

		//test absolutely all conditions
		//Our PSR works well (already tested) so we just put values into PSR :)

		// EQ & NE
		psr.setFlags(2);
		mem.setWord(0x55, new core.InstructionClass("JEQ [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x56);
		
		mem.setWord(0x56, new core.InstructionClass("JNE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x57);

		psr.setFlags(1);
		mem.setWord(0x57, new core.InstructionClass("JEQ [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x58);
		
		mem.setWord(0x58, new core.InstructionClass("JNE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x59);

		// CS & CC
		psr.setFlags(1);
		mem.setWord(0x59, new core.InstructionClass("JCS [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x5A);
		
		mem.setWord(0x5A, new core.InstructionClass("JCC [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x5B);

		psr.setFlags(2);
		mem.setWord(0x5B, new core.InstructionClass("JCS [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x5C);
		
		mem.setWord(0x5C, new core.InstructionClass("JCC [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x5D);

		// plus & minus
		psr.setFlags(4);
		mem.setWord(0x5D, new core.InstructionClass("JMI [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x5E);
		
		mem.setWord(0x5E, new core.InstructionClass("JPL [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x5F);

		psr.setFlags(2);
		mem.setWord(0x5F, new core.InstructionClass("JMI [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x60);
		
		mem.setWord(0x60, new core.InstructionClass("JPL [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x61);

		//HI
		psr.setFlags(1);
		mem.setWord(0x61, new core.InstructionClass("JHI [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x62);

		psr.setFlags(3);
		mem.setWord(0x62, new core.InstructionClass("JHI [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x63);

		//LS
		psr.setFlags(0);
		mem.setWord(0x63, new core.InstructionClass("JLS [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x64);

		psr.setFlags(2);
		mem.setWord(0x64, new core.InstructionClass("JLS [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x65);

		psr.setFlags(1);
		mem.setWord(0x65, new core.InstructionClass("JLS [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x66);

		//LT
		psr.setFlags(4);
		mem.setWord(0x66, new core.InstructionClass("JLT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x67);

		psr.setFlags(8);
		mem.setWord(0x67, new core.InstructionClass("JLT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x68);

		psr.setFlags(13);
		mem.setWord(0x68, new core.InstructionClass("JLT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x69);

		psr.setFlags(0);
		mem.setWord(0x69, new core.InstructionClass("JLT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x6A);

		//LE
		psr.setFlags(6);
		mem.setWord(0x6A, new core.InstructionClass("JLE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x6B);

		psr.setFlags(3);
		mem.setWord(0x6B, new core.InstructionClass("JLE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x6C);

		psr.setFlags(13);
		mem.setWord(0x6C, new core.InstructionClass("JLE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x6D);

		psr.setFlags(0);
		mem.setWord(0x6D, new core.InstructionClass("JLE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x6E);

		//GE
		psr.setFlags(13);
		mem.setWord(0x6E, new core.InstructionClass("JGE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x71);

		psr.setFlags(0);
		mem.setWord(0x71, new core.InstructionClass("JGE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x72);

		psr.setFlags(4);
		mem.setWord(0x72, new core.InstructionClass("JGE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x73);

		psr.setFlags(8);
		mem.setWord(0x73, new core.InstructionClass("JGE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x74);

		psr.setFlags(4);
		mem.setWord(0x74, new core.InstructionClass("JGE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x75);

		psr.setFlags(6);
		mem.setWord(0x75, new core.InstructionClass("JGE [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x76);

		//GT
		psr.setFlags(12);
		mem.setWord(0x76, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x77);

		psr.setFlags(0);
		mem.setWord(0x77, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x200);
		cu.setPC((short)0x78);

		psr.setFlags(15);
		mem.setWord(0x78, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x79);

		psr.setFlags(10);
		mem.setWord(0x79, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x7A);

		psr.setFlags(9);
		mem.setWord(0x7A, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x7B);

		psr.setFlags(5);
		mem.setWord(0x7B, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x7C);

		psr.setFlags(4);
		mem.setWord(0x7C, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x7D);

		psr.setFlags(6);
		mem.setWord(0x7D, new core.InstructionClass("JGT [R5]").getByteCode());
		cu.processNextInstruction();
		assert(cu.getPC() == 0x7E);

		System.out.println("Control Unit - Flow Control & Conditionals OK");

		System.out.println("Control Unit OK");
	}
	
	public void runNVerbose(int n, boolean verbose){
		if(verbose){
			for(int i=0; i<n; i++){
				cu.processNextInstructionVerbose();
			}
		}else{
			for(int i=0; i<n; i++){
				cu.processNextInstruction();
			}
		}
	}
	public void testZero(){
		assert(rb.getRegister(0) == 0x0000);
		assert(rb.getRegister(1) == 0x0000);
		assert(rb.getRegister(2) == 0x0000);
		assert(rb.getRegister(3) == 0x0000);
		assert(rb.getRegister(4) == 0x0000);
	}
	public void testValues(){
		assert(rb.getRegister(1) == 0x0001);
		assert(rb.getRegister(2) == 0x0020);
		assert(rb.getRegister(3) == 0x0300);
		assert(rb.getRegister(4) == 0x4000);

	}

	public static void main(String args[]){
		new ControlUnitTest();
	}
}
